package edu.umn.msse.farside.FourH.domain;

import edu.umn.msse.farside.FourH.exceptions.PositionFullException;
import org.hibernate.annotations.IndexColumn;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;

/**
 * User: Farside
 * Date: Feb 6, 2009
 * To change this template use File | Settings | File Templates.
 */

/*
A position will consist of a name, description,
 optional location, number of volunteers required to fill, and optional start and end time.
 */

@Entity
public class Position
{
    @Id
    @GeneratedValue
    private Long id = null; // for Hibernate
    private String name;
    private String description;
    private String location;
    private int numberOfVolunteers;
    @ManyToMany(fetch = FetchType.EAGER)
    @IndexColumn(name = "INDEX_COL")
    private Set<Volunteer> volunteers = new HashSet<Volunteer>();
    private Timestamp startDateAndTime;
    private Timestamp endDateAndTime;

    public Position()
    {
    }

    public Position(String name, String description, int numberOfVolunteers)
    {
        this.name = name;
        this.description = description;
        this.numberOfVolunteers = numberOfVolunteers;
    }

    public Position updatePosition(Position position)
    {
        // only update the non-collection fields of the position
        this.name = position.name;
        this.description = position.description;
        this.location = position.location;
        this.numberOfVolunteers = position.numberOfVolunteers;
        this.startDateAndTime = position.startDateAndTime;
        this.endDateAndTime = position.endDateAndTime;
        return this;
    }

    public Long getId()
    {
        return id;
    }

    public String toString()
    {
        return this.getName();
    }

    public void setId(Long id)
    {
        this.id = id;
    }


    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public int getNumberOfVolunteers()
    {
        return numberOfVolunteers;
    }

    public void setNumberOfVolunteers(int num)
    {
        this.numberOfVolunteers = num;
    }

    public String getLocation()
    {
        return location;
    }

    public void setLocation(String location)
    {
        this.location = location;
    }

    public Set<Volunteer> getVolunteers()
    {
        return volunteers;
    }

    public void setVolunteers(Set<Volunteer> volunteers)
    {
        this.volunteers = volunteers;
    }

    public void addVolunteer(Volunteer volunteer)
    {
        if (volunteers.size() >= numberOfVolunteers)
        {
            throw new PositionFullException();
        }
        this.volunteers.add(volunteer);
    }

    public void removeVolunteer(Volunteer volunteer)
    {
        this.volunteers.remove(volunteer);
    }

    public Timestamp getStartDateAndTime()
    {
        return startDateAndTime;
    }

    public void setStartDateAndTime(Timestamp startDateAndTime)
    {
        this.startDateAndTime = startDateAndTime;
    }

    public void setStartDateAndTime(String startDateAndTime)
    {
        this.startDateAndTime = java.sql.Timestamp.valueOf(startDateAndTime);
    }

    public Timestamp getEndDateAndTime()
    {
        return endDateAndTime;
    }

    public void setEndDateAndTime(Timestamp endDateAndTime)
    {
        this.endDateAndTime = endDateAndTime;
    }

    public void setEndDateAndTime(String endDateAndTime)
    {
        this.endDateAndTime = java.sql.Timestamp.valueOf(endDateAndTime);
    }

    /**
     * Delete the position from the database
     *
     * @param position The position to be deleted
     */
    public void deletePosition(Position position)
    {
        // delete the position from the database
    }

    public int getNumberOfFilledPositions()
    {
        return volunteers.size();
    }

    public int getNumberOfUnfilledPositions()
    {
        return numberOfVolunteers - getNumberOfFilledPositions();
    }

    @Override
    public int hashCode()
    {
        if (id != null)
        {
            return id.hashCode();
        }
        else
        {
            return name.hashCode();
        }
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == this)
        {
            return true;
        }
        if (!(obj instanceof Position))
        {
            return false;
        }
        return ((Position) obj).id.equals(id);
    }
}
